# -*- coding: utf-8 -*-

# Copyright: (c) 2007 by Jarek Zgoda, <jzgoda@o2.pl>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307, USA.

"""Audioscrobbler data provider"""

__revision__ = '$Id: asdata.py 42 2007-08-03 21:53:52Z jarek.zgoda $'

import urllib

# try to import any ElementTree implementation, from the most prolific through
# the most efficient to the basic one
try:
    import xml.etree.ElementTree as ET # in python >=2.5
except ImportError:
    try:
        import cElementTree as ET # effbot's C module
    except ImportError:
        try:
            import lxml.etree as ET # ElementTree API using libxml2
        except ImportError:
            import elementtree.ElementTree as ET # effbot's pure Python module

import common

class AudioscrobblerData(object):
    """Class that retrieves data collected by Audioscrobbler.
    By far, this is not a complete list of available data sources,
    only those that have any use with LastFMService.
    Most of these methods return lists of tuples."""
    
    def get_artist_tags(self, artist):
        """Return artist tag list. Only tags with count > 0 are returned."""
        data = ''
        host = common.WS_URL
        name = urllib.quote(artist.encode('utf-8'))
        url = 'http://%(host)s/1.0/artist/%(name)s/toptags.xml' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tags = []
        root = ET.fromstring(data)
        for child in root.findall('tag'):
            name = child.find('name').text
            try:
                count = int(child.find('count').text)
            except ValueError:
                count = 0
            url = child.find('url').text
            tags.append((name, url))
        return tags

    def get_user_artist_tags(self, user, artist):
        """Return user's tags for artist."""
        data = ''
        host = common.WS_URL
        artist_name = urllib.quote(artist.encode('utf-8'))
        user_name = urllib.quote(user.encode('utf-8'))
        url = 'http://%(host)s/1.0/user/%(user_name)s/artisttags.xml?artist=%(artist_name)s' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tags = []
        root = ET.fromstring(data)
        for child in root.findall('tag'):
            name = child.find('name').text
            url = child.find('url').text
            tags.append((name, url))
        return tags

    def get_album_tags(self, artist, album):
        """It seems even audioscrobbler has nothing to say about this..."""
        return []

    def get_user_album_tags(self, user, artist, album):
        """Return user tags for album."""
        data = ''
        host = common.WS_URL
        artist_name = urllib.quote(artist.encode('utf-8'))
        user_name = urllib.quote(user.encode('utf-8'))
        album_name = urllib.quote(album.encode('utf-8'))
        url = 'http://%(host)s/1.0/user/%(user_name)s/albumtags.xml?artist=%(artist_name)s&album=%(album_name)s' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tags = []
        root = ET.fromstring(data)
        for child in root.findall('tag'):
            name = child.find('name').text
            url = child.find('url').text
            tags.append((name, url))
        return tags

    def get_track_tags(self, artist, track):
        """
        Return tags for particular track. Only tags with use count > 0
        are returned.
        """
        data = ''
        host = common.WS_URL
        artist_name = urllib.quote(artist.encode('utf-8'))
        track_name = urllib.quote(track.encode('utf-8'))
        url = 'http://%(host)s/1.0/track/%(artist_name)s/%(track_name)s/toptags.xml' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tags = []
        root = ET.fromstring(data)
        for child in root.findall('tag'):
            name = child.find('name').text
            try:
                count = int(child.find('count').text)
            except ValueError:
                count = 0
            url = child.find('url').text
            tags.append((name, url))
        return tags

    def get_user_track_tags(self, user, artist, track):
        """
        Returns user's tags for particular track.
        """
        data = ''
        host = common.WS_URL
        artist_name = urllib.quote(artist.encode('utf-8'))
        user_name = urllib.quote(user.encode('utf-8'))
        track_name = urllib.quote(track.encode('utf-8'))
        url = 'http://%(host)s/1.0/user/%(user_name)s/tracktags.xml?artist=%(artist_name)s&track=%(track_name)s' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tags = []
        root = ET.fromstring(data)
        for child in root.findall('tag'):
            name = child.find('name').text
            url = child.find('url').text
            tags.append((name, url))
        return tags

    def get_recent_tracks(self, user):
        """
        Returns list of recently listened tracks.
        """
        data = ''
        host = common.WS_URL
        user_name = urllib.quote(user.encode('utf-8'))
        url = 'http://%(host)s/1.0/user/%(user_name)s/recenttracks.xml' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tracks = []
        root = ET.fromstring(data)
        for child in root.findall('track'):
            artist = child.find('artist').text
            name = child.find('name').text
            url = child.find('url').text
            tracks.append((artist, name, url))
        return tracks

    def get_recent_loved_tracks(self, user):
        """
        Returns list of tracks that was recently added to the "loved" list.
        """
        data = ''
        host = common.WS_URL
        user_name = urllib.quote(user.encode('utf-8'))
        url = 'http://%(host)s/1.0/user/%(user_name)s/recentlovedtracks.xml' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tracks = []
        root = ET.fromstring(data)
        for child in root.findall('track'):
            artist = child.find('artist').text
            name = child.find('name').text
            url = child.find('url').text
            tracks.append((artist, name, url))
        return tracks

    def get_recent_banned_tracks(self, user):
        """
        Returns list of tracks that have been banned by user.
        """
        data = ''
        host = common.WS_URL
        user_name = urllib.quote(user.encode('utf-8'))
        url = 'http://%(host)s/1.0/user/%(user_name)s/recentbannedtracks.xml' % locals()
        fp = urllib.urlopen(url)
        try:
            data = fp.read()
        finally:
            fp.close()
        tracks = []
        root = ET.fromstring(data)
        for child in root.findall('track'):
            artist = child.find('artist').text
            name = child.find('name').text
            url = child.find('url').text
            tracks.append((artist, name, url))
        return tracks
